using System;
using System.Collections.Generic;
using System.Text;

using Weazel.Gezel.Simulator.Reference.IpBlocks;
using Weazel.Microblaze.Simulator.Engine;

namespace Weazel.Microblaze.Simulator.Components.Gezel
{
    public class GezelOpbMaster : Opb.IOpbMaster
    {
        private OpbGezelComponent parent;
        private OpbMaster gezelIpBlock;

        private Transaction transaction;

        public Transaction Transaction
        {
            get { return transaction; }
            set { transaction = value; }
        }

        public GezelOpbMaster(OpbGezelComponent parent, OpbMaster ipBlock)
        {
            this.parent = parent;
            this.gezelIpBlock = ipBlock;

            this.gezelIpBlock.RequestBus = new OpbMaster.RequestBusDelegate(RequestBus);
        }

        public bool RequestBus(bool request)
        {
            return parent.RequestBusAccess(this, request);
        }

        public bool HasPendingTransaction
        {
            get { return transaction != null; } // && transaction.Status != Transaction.TransactionStatus.Complete; }
        }

        public void CheckPendingTransaction()
        {
            if (transaction != null && transaction.Status == Transaction.TransactionStatus.Complete)
            {
                gezelIpBlock.OpbXferAck = true;
                gezelIpBlock.OpbDataBus = transaction.Value;
                transaction = null;
            }
        }

        public void EndTransaction()
        {
            gezelIpBlock.OpbXferAck = true;
        }

        public Transaction GetTransaction()
        {
            transaction = null;

            parent.StepSimulation();

            if (gezelIpBlock.MasterReadNotWrite)
            {
                transaction = new ReadWordTransaction(this, gezelIpBlock.MasterAddressBus);
            }
            else
            {
                transaction = new WriteWordTransaction(this, gezelIpBlock.MasterAddressBus, gezelIpBlock.MasterDataBus);
            }

            return transaction;
        }
    }
}
